#include <tcl.h>

#include "f_unlazy.h"
#include "f_core.h"

// int unlazyTuple(Tcl_Interp *interp,Tcl_Obj *obj);
// int unlazyList(Tcl_Interp *interp,Tcl_Obj *obj);


__inline int
unlazyTuple(Tcl_Interp *interp,Tcl_Obj *obj)
{
    Cons *cons;
    if (obj->typePtr!=tupleType) return TCL_OK;
    for(cons=TUPLE(obj)->head;cons!=NULL;cons=cons->next) {
        if (cons->obj==NULL) continue;
        if (unlazyObj(interp,cons->obj)!=TCL_OK) return TCL_ERROR;
    }
    return TCL_OK;
}

__inline int
unlazyList(Tcl_Interp *interp,Tcl_Obj *obj)
{
    int t;
    int objc;
    Tcl_Obj **objv;
    if (obj->typePtr!=listType) return TCL_OK;
    if (Tcl_ListObjGetElements(interp,obj,&objc,&objv)!=TCL_OK) return TCL_ERROR;
    for(t=0;t<objc;t++) {
        if (unlazyObj(interp,objv[t])!=TCL_OK) return TCL_ERROR;
    }
    return TCL_OK;
}

int
unlazyObj(Tcl_Interp *interp,Tcl_Obj *obj)
{
    if (obj==NULL) return TCL_ERROR;
    if (obj->typePtr==lazyType) lazyObjExec(obj,1);
    if (obj->typePtr==listType) return unlazyList(interp,obj);
    if (obj->typePtr==tupleType) return unlazyTuple(interp,obj);
    return TCL_OK;
}

int
unlazyObjCmd(ClientData data,Tcl_Interp *interp,int objc,Tcl_Obj *const objv[])
{
    int t;
    (void)data;
    if (objc==1) {
        Tcl_Obj *obj;
        obj=Tcl_GetObjResult(interp);
        Tcl_IncrRefCount(obj);
        printf("Obj is: \"%s\"",obj==NULL?"NULL":Tcl_GetString(obj));
        if (unlazyObj(interp,obj)!=TCL_OK) return TCL_ERROR;
        Tcl_SetObjResult(interp,obj);
        Tcl_DecrRefCount(obj);
        return TCL_OK;
    }
    for(t=0;t<objc;t++) {
        if (unlazyObj(interp,objv[t])!=TCL_OK) break;
    }
    if (t!=objc) {
        return TCL_ERROR;
    }
    if (objc==2)
        Tcl_SetObjResult(interp,objv[1]);
    else
        Tcl_SetObjResult(interp,Tcl_NewListObj(objc-1,objv+1));    
    return TCL_OK;
}
